WWW::Mechanize::PhantomJS

Max Maischein

Frankfurt.pm

English Version

English Version

http://corion.net/talks/

(no subtitles, sorry)

Überblick

  • Warum WWW::Mechanize::PhantomJS?

  • Was ist WWW::Mechanize::PhantomJS?

  • Anwendungen

Wer bin ich?

  • Max Maischein

  • DZ BANK Frankfurt

  • Deutsche Zentralgenossenschaftsbank

  • Integrationsmanagement TxB

Automation - Mein Leitmotiv

  • Wenn ich es tun kann

  • ... kann der Computer es wiederholen

  • ... jedesmal korrekt

Meine Werkzeuge

  • Perl (na klar)

  • Host-Automation (3270, Win32::OLE)

  • WWW::Mechanize

  • WWW::Mechanize::Shell (GPW 2002)

  • WWW::Mechanize::Firefox (2010)

  • ... und jetzt WWW::Mechanize::PhantomJS

Web 2.0

  • Web Anwendungen immer noch im Vormarsch

  • Anwendungen halten Zustand im Client

  • ... verwenden viel Javascript

  • Javascript ist nicht Perls Stärke

Javascript (I)

  • Javascript::SpiderMonkey von Mike Schili, Thomas Busch auf CPAN

  • Nur Javascript, kein DOM

  • Javascript::Engine von Father Chrysostomos/SPROUT auf CPAN

  • Pure Perl, laaangsaam

Javascript (II)

  • Bekannte Anwendung

  • Kompatible Anwendung

  • Interaktive Anwendung

  • WWW::Mechanize::Firefox

Interaktivität ist nicht immer großartig

  • WWW::Mechanize::Firefox möchte ein Fenster

  • WWW::Mechanize::Firefox verwendet meinen Browser

Interaktivität ist nicht immer großartig

  • WWW::Mechanize::Firefox möchte ein Fenster

  • WWW::Mechanize::Firefox verwendet meinen Browser

  • PhantomJS ist Firefox, nur ohne UI

Interaktivität ist nicht immer großartig

  • WWW::Mechanize::Firefox möchte ein Fenster

  • WWW::Mechanize::Firefox verwendet meinen Browser

  • PhantomJS ist WebKit, nur ohne UI

Struktur

  • Mein Programm

  • WWW::Mechanize::PhantomJS

  • Selenium::Remote::Driver

  • ghostdriver

  • PhantomJS

Was ist WWW::Mechanize::PhantomJS

  • ein erweitertes Interface

  • von WWW::Mechanize

  • mit PhantomJS als Backend

WWW::Mechanize::PhantomJS

 1:  my $mech = WWW::Mechanize::PhantomJS->new();
 2:  $mech->get('http://act.useperl.at/ye2014');
 3:  $mech->content_as_png();

Features

  • Normale WWW::Mechanize API

  • Javascript

  • CSS Selektoren (via HTML::Selector::XPath)

  • XPath Selektoren

  • Javascript Fehlermeldungen!

Anwendungen von WWW::Mechanize::PhantomJS

  • Webseiten automatisieren

  • Integrierte JS Unit Tests

  • Nutzereingaben mit Javascript auf dem Server validieren

  • Verrückte Sachen

Live demo

PhantomJS steuern

01-open-local.pl

 1:  my $mech = WWW::Mechanize::PhantomJS->new();
 2:  $mech->get_local('datei.html');

Live demo

Webseite testen

02-dump-links.pl

 1:  my $mech = WWW::Mechanize::PhantomJS->new();
 2:  $mech->get_local('link.html');
 3:
 4:  sleep 5;
 5:  
 6:  print $_->get_attribute('href'),
 7:        "\n\t-> ",
 8:        $_->get_attribute('innerHTML'), "\n"
 9:    for $mech->selector('a.download');

Live demo

Javascript ausführen

03-javascript.pl

 1:  // Javascript
 2:      
 3:      
 4:      
 5:      " ".join(["Just","another","Perl","Hacker"]);

Live demo

Execute Javascript

03-javascript.pl

 1:  # Perl
 2:  
 3:  
 4:  print $mech->eval_in_page(<<'JS');
 5:      " ".join(["Just","another","Perl","Hacker"]);
 6:  JS

Screenshots für Documentation/Logging

  • Chat

  • Javascript+Perl

  • Server-Sent Events

  • Tests

Screenshots für Documentation/Logging

05-screenshot-online.pl

 1:  my $mech = WWW::Mechanize::PhantomJS->new();
 2:  my $url= 'http://mychat.dyn.datenzoo.de:5000';
 3:  print "Loading $url\n";
 4:  $mech->get($url);
 5:
 6:  show_screen;

End-to-end Test von JS app

06-send-chat.pl

 1:  $mech->get($url);
 2:
 3:  sleep 5;
 4:  # Set username
 5:    $mech->eval_in_page(<<'JS', $name);
 6:  ...

End-to-end Test von JS app

06-send-chat.pl

 1:  $mech->get($url);
 2:
 3:  sleep 5;
 4:  # Set username
 5:    $mech->eval_in_page(<<'JS', $name);
 6:        (function(name) {
 7:            set_username(name);
 8:        })(arguments[0]);
 9:  JS
10:  sleep 1;

End-to-end Test von JS app

06-send-chat.pl

 1:  # Send chat
 2:  $mech->eval_in_page(<<'JS', $msg);
 3:      (function(msg) {
 4:          $("#message").val( msg );
 5:          post_chat( document.createEvent('UIEvent') );
 6:      })(arguments[0]);
 7:  JS

End-to-end Test von JS app

06-send-chat.pl

 1:    http://www.youtube.com/v/pir_PJmOz8Q
 2:
 3:    https://twitter.com/cpan_pevans/status/503239001101586432
 4:
 5:    http://i.qkme.me/3pvsb6.jpg

HTML nach PDF konvertieren

07-screenshot-pdf.pl

 1:  my $mech = WWW::Mechanize::PhantomJS->new();
 2:  my $url= 'http://localhost:5000';
 3:  print "Loading $url\n";
 4:  $mech->get($url);
 5:
 6:  $mech->render_content(
 7:      format => 'pdf',
 8:      filename => 'screen.pdf'
 9:  );

Systemvoraussetzungen

  • PhantomJS

  • ghostdriver (im Modul dabei)

  • Patches für Ghostdriver um Selenium zu umgehen (inklusive)

  • WWW::Mechanize

  • Selenium::Driver::Remote

What fehlt?

  • API Implementation (->post() , ...)

  • API Erweiterung

  • Dokumentation

Fehlende API Implementation

  • ->post()

  • Eigene HTTP header (->agent(), ... )

Need-driven Development

  • Leichte Sachen zuerst

  • Selenium ist nur für "User simulation"

  • Keine ->post() Funktion

  • ->post() Funktion halb implementiert

  • ... noch nicht gebraucht

Fehlende API Definition

API für

  • Browserfenster (open, close, popup)

  • Frames (schwacher Selenium support)

  • Downloads

  • Event API? Callback API?

  • Liste der Events seit dem letzten Aufruf

Fehlende Dokumentation

  • ::Firefox Dokumentation

  • W:M::PhantomJS::Examples

  • W:M:PhantomJS::Troubleshooting

  • W:M:PhantomJS::Installation

Was fehlt WWW::Mechanize::PhantomJS?

  • (A)synchrones Event Modell

  • Asynchrone Kommunikation (AnyEvent)

  • Weniger Selenium

Vergleich von ::PhantomJS und ::Firefox

 1:                 PhantomJS      Firefox
 2:  
 3:  Display        Nein           Ja

Vergleich von ::PhantomJS und ::Firefox

 1:                 PhantomJS      Firefox
 2:  
 3:  Display        Nein           Ja
 4:  Cookies
 5:    persistent   Optional       Ja

Vergleich von ::PhantomJS und ::Firefox

 1:                 PhantomJS      Firefox
 2:  
 3:  Display        Nein           Ja
 4:  Cookies
 5:    persistent   Optional       Ja
 6:  Eigene SSL
 7:    Zertifikate  Leicht         Schwer

Vergleich von ::PhantomJS und ::Firefox

 1:                 PhantomJS      Firefox
 2:  
 3:  Display        Nein           Ja
 4:  Cookies
 5:    persistent   Optional       Ja
 6:  Eigene SSL
 7:    Zertifikate  Leicht         Schwer
 8:  Dialoge        Möglich        Schwer

Vergleich von ::PhantomJS und ::Firefox

 1:                 PhantomJS      Firefox
 2:  
 3:  Display        Nein           Ja
 4:  Cookies
 5:    persistent   Optional       Ja
 6:  Eigene SSL
 7:    Zertifikate  Leicht         Schwer
 8:  Dialoge        Möglich        Schwer
 9:  alert()        Ja             Schwer

Beispielcode

Der Code ist auf CPAN in

WWW::Mechanize::PhantomJS::Examples

Danke

Danke

Fragen?

Danke

Fragen?

corion@cpan.org

Folien liegen unter

http://corion.net/talks/

WWW::Mechanize::PhantomJS auf CPAN

https://github.com/corion/www-mechanize-phantomjs auf Github

Bonus Section

Entwicklung von WWW::Mechanize::PhantomJS

Entwicklung von WWW::Mechanize::PhantomJS

The Good

  • Test Suite von WWW::Mechanize::Firefox

  • API von WWW::Mechanize

  • Erfahrung mit ::Firefox

  • 32bit App, 64bit Perl -> TCP!

Entwicklung von WWW::Mechanize::PhantomJS

The Good, the Bad

  • Selenium ist NUR für Browser"interaktion"

  • Selenium mag keine Frames

  • Hacks für ghostdriver-API

  • Keine Patches upstream an ghostdriver-Entwickler

Entwicklung von WWW::Mechanize::PhantomJS

The Good, the Bad, the Ugly

  • Feine Unterschiede zwischen ::Firefox und ::PhantomJS

  • 100% OK bis

     1:  s/::Firefox/::PhantomJS/g

Danke

Fragen?

corion@cpan.org

Folien unter

http://corion.net/talks/

WWW::Mechanize::PhantomJS auf CPAN

https://github.com/corion/www-mechanize-phantomjs auf Github